import axios from "axios"
import { storeToken, isExpire } from "./storeToken"
import store from "store2"
import { refreshTokenApi } from "@/api"
import router from "@/router"

// 创建一个axios实例
const myAxios = axios.create({
  timeout: 5000,
  baseURL: "http://127.0.0.1:5173/dev"
})

// 有没有在刷新token
let isRefresh = false
// token刷新期间等待执行队列
const queq: any = []

// 添加请求拦截器
myAxios.interceptors.request.use(
  async function (config) {
    config.headers.Authorization = store.get("token")

    // 排除刷新token的接口
    if (config.url?.includes("refreshToken")) return config

    // 在token刷新的等待时间中,可能会有请求进入, 如果此时的isRefresh为true,说明token正在刷新,则将其放到等待执行队列中
    if (isRefresh) {
      // todo...
      // 返回一个新的 Promise, 让当前的接口不发出去
      return new Promise((resolve) => {
        // 将当前请求追加到队列中，等到后续再发出
        queq.push((newToken: string) => {
          config.headers.Authorization = newToken
          resolve(config)
        })
      })
    }

    // 判断token有没有过期,如果没有token,则不进行判断,会直接跳转到登录页面
    if (store.get("token") && isExpire(store.get("token_timeout"))) {
      // 过期了
      // 准备刷新,标记token正在刷新
      isRefresh = true
      // 进行token的刷新
      try {
        var res: any = await refreshTokenApi(store.get("refreshToken"))
      } catch (err) {
        // 如果有报错, 则说明刷新token都过期了, 直接打回登录页面
        isRefresh = false
        router.replace({ name: "login" })
      }

      if(!isRefresh){
        return config
      }

      // 如果成功,说明刷新token成功,将新的token和过期时间存在本地
      store.set("token", res.token)
      store.set("expire", res.expire)

      // 再计算下一次过期时间存在本地
      storeToken()

      // 刷新完毕
      isRefresh = false

      console.log("刷新成功")

      // 改变本次请求的请求头
      config.headers.Authorization = store.get("token")
      // 以及被存放在队列中的请求
      queq.forEach((cb: any) => cb(res.token))
    }

    return config
  },
  function (error) {
    return Promise.reject(error)
  }
)

// 添加响应拦截器
myAxios.interceptors.response.use(
  function (res) {
    // 真正的接口返回数据在axios.data上
    const { data: response } = res

    // 把状态码和需要的数据解构出来
    const { code, data } = response

    // 状态码为0才说明成功返回,否则抛出错误
    if (code != 1000) return Promise.reject(response)

    // 成功则返回需要的数据
    return data
  },
  function (error) {
    console.log(error)
    // 对响应错误做点什么
    return Promise.reject(error)
  }
)

export default myAxios
